home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / lists / mint / l_1599 / 1260 < prev    next >
Encoding:
Internet Message Format  |  1994-08-27  |  6.7 KB

  1. Date: Tue, 5 Apr 94 15:59:08 PDT
  2. From: hyc@hanauma.jpl.nasa.gov (Howard Chu)
  3. Message-Id: <9404052259.AA09371@hanauma.jpl.nasa.gov>
  4. To: mint@atari.archive.umich.edu
  5. Subject: Screendump to MacPaint file for MiNT 1.10 + Psigintr
  6.  
  7. Well, I needed something to dump a screen to a MacPaint file, and I couldn't
  8. find anything like that, let alone working under MiNT, thus this program.
  9. The screen rotation code is pretty slow; I'm working on a more efficient one
  10. but it works, so what the heck.
  11.  
  12. Hope someone else finds this useful...  -- Howard
  13.  
  14. /*
  15.  * scrdump - Dump a monochrome screen in MacPaint format. Requires MiNT 1.10
  16.  * plus Psigintr extension. I wrote this program because I've seen no other
  17.  * code that will dump a screen to a file when running under MiNT.
  18.  *
  19.  * The program doesn't put itself into the background, but it ought to.
  20.  * Dump files are named "ScreenXX.MAC" with two hex digits "XX". The program
  21.  * exits after dumping 256 images. If the environment variable SCRDUMPS exists
  22.  * and is set to a GEMDOS-format pathname, dumps will be created in that
  23.  * directory, otherwise they will be in the current working directory.
  24.  *
  25.  * The MacPaint format isn't exactly the greatest format in the world. It's
  26.  * a fixed size, 576 horizontal by 720 vertical. The only reason I used it
  27.  * is because I needed to get some screen dumps to a doc-writer who was using
  28.  * a Mac, and this is the simplest Mac format I had docs for. To get a better
  29.  * fit, I rotate the ST screen 90 degrees before dumping it to disk. For
  30.  * screens larger than 720x576, only the upper left corner gets dumped.
  31.  *
  32.  * Not the best-written stuff in the world, but it works...
  33.  *
  34.  *  -- Howard Chu, howard@lloyd.com    4-5-94
  35.  *    (also at hyc@hanauma.jpl.nasa.gov, but phasing that out.)
  36.  */
  37.  
  38. #include <mintbind.h>
  39. #include <unistd.h>
  40. #include <signal.h>
  41. #include <linea.h>
  42.  
  43. int quit;
  44.  
  45. void sigit (int sig) {
  46.     if (sig != SIGHUP)
  47.         quit = 1;
  48. }
  49.  
  50. /*
  51.  * Once again, a strange problem - how do you get a signal from an interrupt-
  52.  * time routine into a MiNT process. Using Psigintr directly doesn't work here
  53.  * because the ALT-Help vector isn't at a long-word aligned address, and it's
  54.  * invoked as a subroutine, not an exception. Perhaps Psigintr should be
  55.  * changed to take an address instead of a vector number, with another argument
  56.  * telling whether to return with RTE or RTS... ?
  57.  *
  58.  * Anyway, my solution here is to set the ALT-Help vector to point to a
  59.  * routine that invokes an unused trap. Psigintr is called with that trap
  60.  * vector, and so the desired signal gets delivered... What a kludge.
  61.  */
  62.  
  63. #define Prt_cnt    *(short *)0x4eeL
  64. #define    Scr_dump    *(long *)0x502L
  65. #define    TRAP0VEC    0x20
  66.  
  67. void trapper () {
  68.     if (Prt_cnt == 0)
  69.         Prt_cnt = -1;
  70.     __asm__("trap #0");
  71. }
  72.  
  73. long oldprt;
  74.  
  75. void installer () {
  76.     oldprt = Scr_dump;
  77.     Scr_dump = (long)trapper;
  78. }
  79.  
  80. void remover() {
  81.     Scr_dump = oldprt;
  82. }
  83.         
  84. const char digx[]="0123456789ABCDEF";
  85. char file[]="Screen00.MAC";
  86.  
  87. /* MacPaint dimensions */
  88.  
  89. #define    M_X_MAX    576
  90. #define    M_Y_MAX    720
  91. #define    MAC_BUF    ((M_X_MAX*M_Y_MAX>>3)+512)
  92.  
  93. main() {
  94.     int i, j;
  95.     int snum;
  96.     int xmax, ymax;        /* max dimension, unrotated */
  97.     int xlen;
  98.  
  99.     int fd;
  100.     char *scr;
  101.     char *wd, *pbuf;
  102.     char *pt1, *pt2, *pt3, *pt4;
  103.     char c, m1, m2;
  104.  
  105.     /* Go to specified dump directory */
  106.  
  107.     wd = (char *)getenv("SCRDUMPS");
  108.     if (wd) {
  109.         if (wd[1] == ':') {
  110.             Dsetdrv((wd[0] & 0x1f)-1);
  111.             wd += 2;
  112.         }
  113.         Dsetpath(wd);
  114.     }
  115.         
  116.     scr = (char *)Logbase();
  117.  
  118.     /* Yeah, I know Line-A isn't supposed to be used any more, but it
  119.          * still works on TT and Falcon, and there's no where else to find
  120.      * the Bytes_Per_Line value...
  121.      */
  122.  
  123.     linea0();
  124.     xmax = V_X_MAX;
  125.     if (xmax > M_Y_MAX)
  126.         xmax = M_Y_MAX;
  127.     ymax = V_Y_MAX;
  128.     if (ymax > M_X_MAX)
  129.         ymax = M_X_MAX;
  130.     xlen = V_BYTES_LIN;
  131.  
  132.     wd = malloc(MAC_BUF);            /* MacPaint rez + header */
  133.     bzero(wd, MAC_BUF);            /* zero the buffer */
  134.     wd += 512;                /* Skip over the header */
  135.     pbuf = malloc((ymax>>3)+1);        /* 1 PackBits line */
  136.  
  137. #if BORDERS==1
  138.     /* Draw 2-pixel borders if image is smaller than MacPaint size */
  139.  
  140.     if (ymax < M_X_MAX) {
  141.         pt1 = wd + (ymax>>3);
  142.         j = xmax+2;
  143.         if (j > M_Y_MAX) j = M_Y_MAX;
  144.         for (i=0; i<j; i++) {
  145.         *pt1 = 0xc0;
  146.         pt1 += (M_X_MAX>>3);
  147.         }
  148.     }
  149.  
  150.     if (xmax < M_Y_MAX-1) {
  151.         pt1 = wd + xmax*(M_X_MAX>>3);
  152.         for (i=0; i<ymax>>3; i++)
  153.         *pt1++ = 0xff;
  154.         pt1 += (M_X_MAX-ymax) >> 3;
  155.         for (i=0; i<ymax>>3; i++)
  156.         *pt1++ = 0xff;
  157.     }
  158. #endif
  159.  
  160.     /* Use trap 0 vector to signal us */
  161.  
  162.     signal(SIGHUP, sigit);
  163.     signal(SIGINT, sigit);
  164.     signal(SIGQUIT, sigit);
  165.     signal(SIGTERM, sigit);
  166.     
  167.     Psigintr(TRAP0VEC, SIGHUP);
  168.     Supexec(installer);
  169.  
  170.     for(snum=0;snum<256;snum++) {
  171.  
  172.         /* Set file name */
  173.  
  174.         file[7] = digx[snum & 0x0f];
  175.         file[6] = digx[snum >> 4];
  176.  
  177.         /* Wait for ALT-Help signal */
  178.  
  179.         Pause();
  180.         if (quit)
  181.             break;
  182.  
  183.         /* Open output file, write header */
  184.  
  185.         fd = Fcreate(file, 0);
  186.         if (fd < 0)
  187.             continue;
  188.  
  189.         Fwrite(fd, 512, wd-512);
  190.  
  191.         /* Rotate image 90 degrees */
  192.  
  193.         pt1=scr + (xmax>>3)-1;    /* Far right src column */
  194.         pt2=wd + ((M_X_MAX*(xmax-1)+ymax)>>3)-1;
  195.                     /* lower right corner */
  196.         for (i=0, m1=1; i<xmax; i++) {
  197.             pt3 = pt1;    /* input */
  198.             m2 = 1;
  199.             for (j=0, c=0; j<ymax; j++) {
  200.             if (*pt3 & m1)
  201.                c |= m2;
  202.             pt3 += xlen;
  203.             if (m2 < 0) {
  204.                m2 = 1;
  205.                *pt2-- = c;
  206.                c = 0;
  207.             } else {
  208.                m2 += m2;
  209.             }
  210.         
  211.             }
  212.             pt2 -= ((M_X_MAX-ymax)>>3);
  213.             if (m1 < 0) {        /* signed char */
  214.             m1 = 1;
  215.             pt1--;
  216.             } else {
  217.             m1 += m1;
  218.             }
  219.         }
  220.             
  221.         /* Write output in PackBits format */
  222.  
  223.         pt1 = wd;
  224. #if PACKBITS==1
  225.         for (i=0; i<M_Y_MAX; i++) {    /* For each line */
  226.             m1 = 0;            /* No repeats */
  227.             m2 = *pt1+1;        /* Previous char */
  228.             pt3 = pt1;         /* beginning of literal */
  229.             pt4 = 0;        /* beginning of run */
  230.             pt2 = pbuf;
  231.             for (j=0; j<M_X_MAX>>3; j++) {
  232.             if (*pt1 == m2)    {
  233.                 if (pt4) {        /* Accumulate repeats */
  234.                 m1++;
  235.                 } else if (j<((M_X_MAX>>3)-1) && pt1[1] == m2) {
  236.                 pt4 = pt1-1;    /* Initialize repeats */
  237.                 m1 = 3;
  238.                 ++j;
  239.                 ++pt1;
  240.                 if (pt3 < pt4) {    /* flush literals */
  241.                     *pt2++ = pt4-pt3-1;
  242.                     for (;pt3 < pt4;)
  243.                         *pt2++ = *pt3++;
  244.                 }
  245.                 }
  246.                 pt1++;
  247.             } else {
  248.                 if (m1) {        /* End of run, how many? */
  249.                 --m1;
  250.                 *pt2++ = -m1; 
  251.                 *pt2++ = m2;
  252.                 pt3 = pt1;
  253.                 pt4 = 0;
  254.                 m1 = 0;
  255.                 }
  256.                 m2 = *pt1++;    /* set prev char */
  257.             }
  258.             }
  259.  
  260.         /* Dump end of line */
  261.  
  262.             if (m1) {            /* finish repeats */
  263.             --m1;
  264.             *pt2++ = -m1;
  265.             *pt2++ = m2;
  266.             } else if (pt3 < pt1) {    /* finish literals */
  267.             *pt2++ = pt1-pt3-1;
  268.             for(;pt3 < pt1;)
  269.                 *pt2++ = *pt3++;
  270.             }
  271.             Fwrite(fd, pt2 - pbuf, pbuf);
  272.         }
  273. #else
  274.         /* Dump it straight, no repeat-suppression */
  275.  
  276.         c = (M_X_MAX>>3)-1;
  277.         for (i=0; i<M_Y_MAX; i++) {
  278.             Fwrite(fd, 1, &c);
  279.             Fwrite(fd, c+1, pt1);
  280.             pt1 += c+1;
  281.         }
  282. #endif                    
  283.         Fclose(fd);
  284.     }
  285.     Supexec(remover);
  286. }
  287.